home *** CD-ROM | disk | FTP | other *** search
- /* handle frames around objects: drawing, resizing, zooming, and
- adjusting the cursor
- 94/01/10 aih - upper-cased constants for consistency with other code
- 93/11/29 aih - created */
-
- #include "DrawLib.h"
- #include "MathLib.h"
- #include "MemoryLib.h"
- #include "RectangleLib.h"
- #include "ScrollBarLib.h"
- #include "FrameLib.h"
- #include "WindowLib.h"
-
- Boolean FrameValid(FrameHandle frame)
- {
- if (! HandleValidSize(frame, sizeof(FrameType))) return(false);
- if ((**frame).margin < 0) return(false);
- return(true);
- }
-
- FrameHandle FrameBegin(WindowPtr window, const Rect *bounds, short margin)
- {
- FrameHandle frame = NULL;
- RgnHandle rgn = NULL;
-
- require(RectValid(bounds));
- require(margin >= 0);
- TRY {
- frame = HandleBeginClear(sizeof(FrameType));
- (**frame).window = window;
- (**frame).bounds = *bounds;
- (**frame).margin = margin;
- (**frame).flags = FRAME_ANCHOR_RIGHT | FRAME_ANCHOR_BOTTOM;
- WinRegister(window, frame, FrameEventTable());
- } CATCH {
- FrameEnd(frame);
- } ENDTRY;
- ensure(FrameValid(frame));
- return(frame);
- }
-
- void FrameEnd(FrameHandle frame)
- {
- if (frame) {
- WinUnregister((**frame).window, frame);
- HandleEnd(frame);
- }
- }
-
- FrameFlagsType FrameFlags(FrameHandle frame)
- {
- require(FrameValid(frame));
- return((**frame).flags);
- }
-
- void FrameFlagsSet(FrameHandle frame, FrameFlagsType flags)
- {
- require(FrameValid(frame));
- (**frame).flags = flags;
- }
-
- Boolean FrameFlagTest(FrameHandle frame, FrameFlagsType flags)
- {
- return((FrameFlags(frame) & flags) != 0);
- }
-
- void FrameFlagSet(FrameHandle frame, FrameFlagsType flags, Boolean set)
- {
- require(FrameValid(frame));
- if (set)
- (**frame).flags |= flags;
- else
- (**frame).flags &= ~flags;
- ensure(FrameFlagTest(frame, flags) == set);
- }
-
- void FrameActivate(FrameHandle frame, Boolean active)
- {
- if (FrameFlagTest(frame, FRAME_ACTIVE) != active) {
- FrameFlagSet(frame, FRAME_ACTIVE, active);
- if (FrameFlagTest(frame, FRAME_LIST))
- FrameDraw(frame);
- }
- }
-
- void FrameFocus(FrameHandle frame, Boolean focus)
- {
- if (FrameFlagTest(frame, FRAME_FOCUS) != focus) {
- FrameFlagSet(frame, FRAME_FOCUS, focus);
- if (FrameFlagTest(frame, FRAME_LIST))
- FrameDraw(frame);
- }
- }
-
- Boolean FrameHilite(FrameHandle frame)
- {
- if (((**frame).flags & FRAME_ACTIVE) == 0) return(false);
- if (((**frame).flags & FRAME_KEEP_INACTIVE) != 0) return(false);
- if (((**frame).flags & FRAME_KEEP_ACTIVE) != 0) return(true);
- return(((**frame).flags & FRAME_FOCUS) != 0);
- }
-
- void FrameCursor(FrameHandle frame, short cursor)
- {
- require(FrameValid(frame));
- (**frame).cursor = cursor;
- }
-
- void FrameContent(FrameHandle frame, Rect *content)
- {
- require(FrameValid(frame));
- *content = (**frame).bounds;
- if (((**frame).flags & FRAME_LIST) != 0)
- InsetRect(content, FRAME_FOCUS_SIZE, FRAME_FOCUS_SIZE);
- if (((**frame).flags & FRAME_VSCROLL) != 0) content->right -= SBAR_WIDTH - 1;
- if (((**frame).flags & FRAME_HSCROLL) != 0) content->bottom -= SBAR_WIDTH - 1;
- InsetRect(content, FRAME_WIDTH + (**frame).margin,
- FRAME_WIDTH + (**frame).margin);
- ensure(RectValid(content));
- }
-
- void FrameBounds(FrameHandle frame, Rect *bounds)
- {
- require(FrameValid(frame));
- *bounds = (**frame).bounds;
- ensure(RectValid(bounds));
- }
-
- short FrameMinWidth(FrameHandle frame)
- {
- require(FrameValid(frame));
- return
- 2 * FRAME_WIDTH +
- 2 * (**frame).margin +
- 2 * (((**frame).flags & FRAME_LIST) != 0 ? FRAME_FOCUS_SIZE : 0) +
- SBarMinWidth(((**frame).flags & FRAME_HSCROLL) != 0,
- ((**frame).flags & FRAME_VSCROLL) != 0);
- }
-
- short FrameMinHeight(FrameHandle frame)
- {
- require(FrameValid(frame));
- return
- 2 * FRAME_WIDTH +
- 2 * (**frame).margin +
- 2 * (((**frame).flags & FRAME_LIST) != 0 ? FRAME_FOCUS_SIZE : 0) +
- SBarMinHeight(((**frame).flags & FRAME_HSCROLL) != 0,
- ((**frame).flags & FRAME_VSCROLL) != 0);
- }
-
- Boolean FrameWithin(FrameHandle frame, Point where)
- {
- Rect bounds;
- FrameBounds(frame, &bounds);
- if (((**frame).flags & FRAME_LIST) != 0)
- InsetRect(&bounds, FRAME_FOCUS_SIZE, FRAME_FOCUS_SIZE);
- return(PtInRect(where, &bounds));
- }
-
- static void FrameDoDraw(FrameHandle frame, RgnHandle border1, RgnHandle border2,
- RgnHandle border3)
- {
- Rect content, bounds;
- GrafPtr port = NULL;
-
- require(FrameValid(frame));
- GetPort(&port);
- SetPort((**frame).window);
- FrameContent(frame, &content);
- InsetRect(&content, -(FRAME_WIDTH + (**frame).margin),
- -(FRAME_WIDTH + (**frame).margin));
- if (border1)
- BorderRgn(&content, FRAME_WIDTH, (**frame).margin, false, border1);
- else
- BorderDraw(&content, FRAME_WIDTH, (**frame).margin, true);
- FrameBounds(frame, &bounds);
- if (((**frame).flags & FRAME_LIST) != 0) {
- if (border2)
- BorderRgn(&bounds, 2, 1, false, border2);
- else
- BorderDraw(&bounds, 2, 1, FrameHilite(frame));
- InsetRect(&bounds, FRAME_FOCUS_SIZE, FRAME_FOCUS_SIZE);
- if (((**frame).flags & FRAME_HSCROLL) != 0 ||
- ((**frame).flags & FRAME_VSCROLL) != 0)
- {
- /* when a list is not active, the List Manager doesn't draw
- a frame around the scroll bars, so we draw it here */
- if (border3)
- BorderRgn(&bounds, 1, 0, false, border3);
- else
- BorderDraw(&bounds, 1, 0, true);
- }
- }
- SetPort(port);
- }
-
- void FrameDraw(FrameHandle frame)
- {
- FrameDoDraw(frame, NULL, NULL, NULL);
- }
-
- void FrameGrow(FrameHandle frame, Rect *size)
- {
- Rect bounds, port;
-
- require(FrameValid(frame));
- FrameBounds(frame, &bounds);
- WinPortRect((**frame).window, &port);
- if (((**frame).flags & FRAME_ANCHOR_RIGHT) != 0)
- size->left = RectWidth(&port) - RectWidth(&bounds) + FrameMinWidth(frame);
- if (((**frame).flags & FRAME_ANCHOR_BOTTOM) != 0)
- size->top = RectHeight(&port) - RectHeight(&bounds) + FrameMinHeight(frame);
- }
-
- void FrameZoom(FrameHandle frame, short *width, short *height)
- {
- Rect bounds, content, port;
- Point border;
-
- require(FrameValid(frame));
- FrameContent(frame, &content);
- FrameBounds(frame, &bounds);
- WinPortRect((**frame).window, &port);
- if (((**frame).flags & FRAME_ANCHOR_RIGHT) == 0)
- *width = RectWidth(&content);
- if (((**frame).flags & FRAME_ANCHOR_BOTTOM) == 0)
- *height = RectHeight(&content);
- border.h = RectWidth(&bounds) - RectWidth(&content);
- border.v = RectHeight(&bounds) - RectHeight(&content);
- *width = min(SHRT_MAX, max((long) *width + border.h, FrameMinWidth(frame)) +
- RectWidth(&port) - RectWidth(&bounds));
- *height = min(SHRT_MAX, max((long) *height + border.v, FrameMinHeight(frame)) +
- RectHeight(&port) - RectHeight(&bounds));
- }
-
- void FrameResize(FrameHandle frame, short dh, short dv)
- {
- #define NBRDR (3)
- #define NRGN (2 * NBRDR)
- RgnHandle rgn[NRGN];
- short i = 0;
- Rect r1, r2;
- GrafPtr port = NULL;
-
- require(FrameValid(frame));
- for (i = 0; i < NRGN; i++)
- rgn[i] = NULL;
- TRY {
- if (((**frame).flags & FRAME_ANCHOR_RIGHT) == 0) dh = 0;
- if (((**frame).flags & FRAME_ANCHOR_BOTTOM) == 0) dv = 0;
- if (dh || dv) {
- for (i = 0; i < NRGN; i++)
- rgn[i] = BeginRgn();
- GetPort(&port);
- SetPort((**frame).window);
- FrameDoDraw(frame, rgn[0], rgn[1], rgn[2]);
- r1 = (**frame).bounds;
- check(RectWidth(&r1) + dh >= FrameMinWidth(frame));
- check(RectHeight(&r1) + dv >= FrameMinHeight(frame));
- (**frame).bounds.bottom += dv;
- (**frame).bounds.right += dh;
- r2 = (**frame).bounds;
- InvalXorRect(&r1, &r2);
- FrameDoDraw(frame, rgn[3], rgn[4], rgn[5]);
- //debug_note
- for (i = 0; i < NRGN; i++) {
- EraseRgn(rgn[i]);
- InvalRgn(rgn[i]);
- }
- //for (i = 0; i < NBRDR; i++)
- // InvalXorRgn(rgn[i], rgn[i + NBRDR]);
- }
- } CLEANUP {
- for (i = 0; i < NRGN; i++) EndRgn(rgn[i]);
- if (port) SetPort(port);
- } ENDTRY;
- }
-
- Boolean FrameAdjustCursor(FrameHandle frame, Point where, RgnHandle cursorRgn)
- {
- GrafPtr port;
- Rect contentRect;
- Boolean result = false;
- RgnHandle contentRgn, visRgn;
-
- require(FrameValid(frame));
- require(ValidateRgn(cursorRgn));
- /* If the cursor is within the frame's content rectangle then set the cursor
- region to the content region and return true. Otherwise, subtract the
- content region from the cursor region and return false. */
- if ((**frame).cursor) {
- GetPort(&port);
- SetPort((**frame).window);
- contentRgn = BeginRgn();
- visRgn = BeginRgn();
- FrameContent(frame, &contentRect);
- RectPortToGlobal(&contentRect, (**frame).window);
- RectRgn(contentRgn, &contentRect);
- CopyRgn((**frame).window->visRgn, visRgn);
- LocalToGlobalRgn(visRgn);
- SectRgn(visRgn, contentRgn, contentRgn);
- if (PtInRgn(where, contentRgn)) {
- CopyRgn(contentRgn, cursorRgn);
- DrawCursor((**frame).cursor);
- result = true;
- }
- else
- DiffRgn(cursorRgn, contentRgn, cursorRgn);
- EndRgn(contentRgn);
- EndRgn(visRgn);
- SetPort(port);
- }
- return(result);
- }
-